#include "openssl.h"


SSL_CTX* OpenSSL::ctx_ = nullptr;

OpenSSL::OpenSSL()
{
}

OpenSSL::~OpenSSL()
{
}

void OpenSSL::initOpenSSL()
{
  /*为打印调试信息作准备*/
  SSL_load_error_strings();
  //进行一些必要的初始化工作
  OpenSSL_add_ssl_algorithms();;

  ctx_ = createSSLContextServer();
}

void OpenSSL::cleanup()
{
  SSL_CTX_free(ctx_);
  EVP_cleanup();
}

void OpenSSL::print_ssl_error(const char* prefix) 
{
  unsigned long err = ERR_get_error();
  char errstr[256];
  ERR_error_string_n(err, errstr, sizeof(errstr));
  std::cerr << prefix << " SSL error: " << errstr << std::endl;
}

SSL_CTX* OpenSSL::createSSLContextServer()
{
  const SSL_METHOD* method = TLSv1_2_server_method();
  SSL_CTX* ctx = SSL_CTX_new(method);
  if (!ctx) 
  {
    print_ssl_error("Failed to create SSL context (server)");
    return nullptr;
  }

  if (SSL_CTX_use_certificate_file(ctx, "./certificate/server.crt", SSL_FILETYPE_PEM) <= 0) 
  {
    print_ssl_error("Failed to load server certificate");
    SSL_CTX_free(ctx);
    return nullptr;
  }

  if (SSL_CTX_use_PrivateKey_file(ctx, "./certificate/server.key", SSL_FILETYPE_PEM) <= 0) 
  {
    print_ssl_error("Failed to load server private key");
    SSL_CTX_free(ctx);
    return nullptr;
  }

  if (!SSL_CTX_check_private_key(ctx)) {
    std::cerr << "Private key does not match the certificate public key" << std::endl;
    SSL_CTX_free(ctx);
    return nullptr;
  }

  return ctx;
  
}
  
   /*绑定读写套接字*/
void OpenSSL::sslSetfd(SSL* ssl, int fd)
{
  SSL_set_fd(ssl, fd);
}

  // 进行 SSL 握手
int OpenSSL::sslAccept(SSL* ssl)
{
  return SSL_accept(ssl);
}

int OpenSSL::sslRead(SSL* ssl, void* buff, int bufflen)
{
  return SSL_read(ssl, buff, bufflen);
}

int OpenSSL::sslWrite(SSL* ssl, const void* message, int messlen)
{
  return SSL_write(ssl, message, messlen);
}
